﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Web.Mvc;
using Xenta.Utils;
using Xenta.Attributes;
using Xenta.Web.Controllers;

namespace Xenta.Web.Areas.Commerce.Controllers
{
    [Authenticate, InRole("ADMIN")]
    public sealed class SellerController : ExtController
    {
        #region GET/POST Actions

        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult GoTo(int? id, int? accountID)
        {
            if(!id.HasValue && accountID.HasValue)
            {
                var m = Svc.ProcessOperation("GetCustomerByAccount", new
                {
                    AccountID = accountID
                });
                id = m != null ? JDM.Int32(m.EntityID) : null;
            }
            if(!id.HasValue)
                return HttpNotFound();
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpGet, RestoreState]
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost, PersistState]
        public ActionResult Create(int accountID, string displayName, string[] flags)
        {
            try
            {
                var m = Svc.ProcessOperation("CreateSeller", new
                {
                    AccountID = accountID,
                    DisplayName = displayName,
                    Flags = flags.Merge(",")
                });
                return RedirectToAction(Loc.Act("Edit").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }));
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Create"));
        }

        [HttpGet, RestoreState]
        public ActionResult Edit(int id)
        {
            var m = Svc.ProcessOperation("GetSeller", new
            {
                EntityID = id,
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m == null)
                return HttpNotFound();
            return View(m);
        }

        [HttpPost, PersistState]
        public ActionResult Update(int id, string displayName, string[] flags)
        {
            try
            {
                Svc.ProcessOperation("UpdateSeller", new
                {
                    EntityID = id,
                    DisplayName = displayName,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }

            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpGet, PersistState]
        public ActionResult Delete(int id)
        {
            try
            {
                Svc.ProcessOperation("DeleteSeller", new
                {
                    EntityID = id
                });
                return RedirectToAction(Loc.Act("Index"));
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpPost, PersistState]
        public ActionResult CreateAddress(int sellerID,
            int countryID,
            int regionID,
            string city,
            string address1,
            string address2,
            string entityName,
            string contactName,
            string postalCode,
            string phoneNumber,
            string faxNumber,
            string email,
            string website,
            string[] flags)
        {
            try
            {
                Svc.ProcessOperation("CreateSellerAddress", new
                {
                    HolderID = sellerID,
                    CountryID = countryID,
                    RegionID = regionID,
                    City = city,
                    Address1 = address1,
                    Address2 = address2,
                    EntityName = entityName,
                    ContactName = contactName,
                    PostalCode = postalCode,
                    PhoneNumber = phoneNumber,
                    FaxNumber = faxNumber,
                    Email = email,
                    Website = website,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = sellerID
            }));
        }

        [HttpPost, PersistState]
        public ActionResult UpdateAddress(int id,
            int sellerID,
            int countryID,
            int regionID,
            string city,
            string address1,
            string address2,
            string entityName,
            string contactName,
            string postalCode,
            string phoneNumber,
            string faxNumber,
            string email,
            string website,
            string[] flags)
        {
            try
            {
                Svc.ProcessOperation("UpdateSellerAddress", new
                {
                    EntityID = id,
                    CountryID = countryID,
                    RegionID = regionID,
                    City = city,
                    Address1 = address1,
                    Address2 = address2,
                    EntityName = entityName,
                    ContactName = contactName,
                    PostalCode = postalCode,
                    PhoneNumber = phoneNumber,
                    FaxNumber = faxNumber,
                    Email = email,
                    Website = website,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = sellerID
            }));
        }

        [HttpGet, PersistState]
        public ActionResult DeleteAddress(int id, int sellerID)
        {
            try
            {
                Svc.ProcessOperation("DeleteSellerAddress", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = sellerID
            }));
        }

        #endregion

        #region AJAX Actions

        [HttpPost]
        public ActionResult Grid(int? page, 
            int? rows, 
            string sord, 
            string sidx,
            string searchTerm)
        {
            page = page.HasValue ? page.Value - 1 : 0;
            rows = rows.HasValue ? rows.Value : 30;
            sord = sord.Equals("desc") ? "Descending" : "Ascending";

            var m = Svc.ProcessOperation("SearchSellers", new 
            {
                Term = new
                {
                    Expression = searchTerm
                },
                Index = page * rows,
                Count = rows,
                SortBy = new[] 
                {
                    sidx
                },
                SortDir = sord
            }, new
            {
                DisclosureLevel = "Base"
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                data.Add(new[] { 
                    JDM.Int32(i.EntityID),
                    JDM.String(i.Account.Email),
                    JDM.String(i.DisplayName),
                    JDM.Int32(i.CommentCount),
                    JDM.Int32(i.RatingCount),
                    JDM.Byte(i.RatingAverage)
                });
            }

            return Json(new
            {
                pageIndex = page + 1,
                pageCount = Math.Ceiling(JDM.Double(m.TotalCount) / rows),
                totalCount = JDM.Int64(m.TotalCount),
                data = data.ToArray()
            });
        }

        [HttpPost]
        public ActionResult Autocomplete(string term)
        {
            var m = Svc.ProcessOperation("GetSellerDictionary", new
            {
                Term = new
                {
                    Expression = String.Format("{0}%", term)
                },
                Count = 10
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                data.Add(new
                {
                    id = JDM.String(i.Key),
                    value = JDM.String(i.Value)
                });
            }
            return Json(data.ToArray());
        }

        [HttpPost]
        public ActionResult Addresses(int sellerID)
        {
            var m = Svc.ProcessOperation("SearchSellerAddresses", new
            {
                HolderID = sellerID
            }, new
            {
                DisclosureLevel = "Base"
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                data.Add(new
                {
                    id = JDM.Int32(i.EntityID),
                    value = JDM.String(i.ShortForm)
                });
            }
            return Json(data.ToArray());
        }

        #endregion

        #region Child Actions

        [ChildActionOnly]
        public ActionResult _Ratings(int sellerID)
        {
            dynamic m = new ExpandoObject();

            m.EntityID = sellerID;
            m.Ratings = Svc.ProcessOperation("SearchSellerRatings", new
            {
                HolderID = sellerID
            }, new
            {
                DisclosureLevel = "Extended"
            }).Items;

            return PartialView(m);
        }

        [ChildActionOnly]
        public ActionResult _Comments(int sellerID)
        {
            dynamic m = new ExpandoObject();

            m.EntityID = sellerID;
            m.Comments = Svc.ProcessOperation("SearchSellerComments", new
            {
                HolderID = sellerID
            }, new
            {
                DisclosureLevel = "Extended"
            }).Items;

            return PartialView(m);
        }

        #endregion
    }
}
